在前面這兩天有聊到 NavigationStack 和 NavigationLink 。NavigationStack 可以創建出 UINavigationController 那樣子的畫面,而 NavigationLink 可以達成和 push view controller 一樣的效果。
NavigationLink("下一頁") {
SomeView()
}
NavigationLink 能夠像這樣子,透過 closure 可以回傳想要顯示的 UI 元件
但是當有畫面中有多個和不同種類的 NavigationLink 的時候,就會充斥著這一類型的 closures 。
這時候就可以透過 navigationDestination 來統整。
struct ContentView: View {
private let flavors = ["綠豆", "紅豆", "芋粿", "愛玉"]
var body: some View {
NavigationStack {
ForEach(flavors, id: \.self) { flavor in
NavigationLink(flavor) {
Text(flavor)
.navigationTitle(flavor)
}
.padding()
}
}
}
}
這時候 navigationDestination 需要加入和第二個參數 value
吻合的型別,在這邊則是 String 。
而到 navigationDestination 的 closure 裡就能夠接收到傳入 value 的值。
struct ContentView: View {
private let flavors = ["綠豆", "紅豆", "芋粿", "愛玉"]
var body: some View {
NavigationStack {
ForEach(flavors, id: \.self) { flavor in
NavigationLink(flavor, value: flavor).padding()
}
.navigationDestination(for: String.self) { flavor in
Text(flavor)
.navigationTitle(flavor)
}
}
}
}
由於 String 這個型別太廣泛,因此我們可以像這樣定義一個 Flavor 、在 navigationDestination 的地方就能夠特定到 Flavor 這個型別了:
struct Flavor: Identifiable, Hashable {
let id = UUID().uuidString
let name: String
}
struct ContentView: View {
private let flavors = ["綠豆", "紅豆", "芋粿", "愛玉"].map(Flavor.init)
var body: some View {
NavigationStack {
ForEach(flavors) { flavor in
NavigationLink(flavor.name, value: flavor).padding()
}
.navigationDestination(for: Flavor.self) { flavor in
Text(flavor.name)
.navigationTitle(flavor.name)
}
}
}
}
以上,那今天的 SwiftUI 的大大小小就到這邊,明天見!
本篇使用到的 UI 元件和 modifiers 基本上沒有受到版本更新影響。若要在 Xcode 14 等環境下使用也是沒問題的。